﻿using System.Collections.Generic;
using System.Xml;
using FogOutlook.Plugins.Classes;
using Microsoft.Office.Interop.Outlook;
using UBR.Products.TimeTrakker.Client.Lib.FogBugz;
using System.Web;
using System.Text;
using System.IO;
using System.Net;
using SHDocVw;

namespace FogBugz {
	internal class FogBugz : BugTrackerBase {
		internal FBApi api = null;

		public Dictionary<string, XmlNodeList> data = new Dictionary<string, XmlNodeList>();

		protected override string GetName() {
			return "FogBugz";
		}

		private static string FixURL(string url) {
			if(url[url.Length - 1] != '/')
				url += '/';
			url += "api.asp";
			return url;
		}

		protected override void Login(string username, string password) {
			FBApi.Url = FixURL(url);
			api = new FBApi(username, password);
		}

		public override void OpenBugReport(Microsoft.Office.Interop.Outlook.MailItem mi, string senderAddress) {
			base.OpenBugReport(mi, senderAddress);
			using(FogBugzReport report = new FogBugzReport(this, mi)) {
				report.Icon = icon;
				if(report.ShowDialog() == System.Windows.Forms.DialogResult.OK)
					ShowConfirmationDialog(report.result);
			}
		}

		public override void DirectReport(string project, MailItem mi, string senderAddress, bool incatt) {
			base.DirectReport(project, mi, senderAddress, incatt);
			Dictionary<string, string> args = new Dictionary<string, string>();
			args.Add("sTitle", mi.Subject);
			args.Add("sEvent", mi.Body.Replace("HYPERLINK", ""));
			args.Add("sCustomerEmail", senderAddress);
			args.Add("sProject", project);
			Dictionary<string, byte[]>[] rgFiles = null;
			if(mi.Attachments.Count > 0 && incatt) {
				ASCIIEncoding encoding = new ASCIIEncoding();
				rgFiles = new Dictionary<string, byte[]>[mi.Attachments.Count];
				int i=0;
				foreach(Attachment att in mi.Attachments) {
					rgFiles[i] = new Dictionary<string, byte[]>();
					rgFiles[i]["name"] = encoding.GetBytes("File" + (i + 1).ToString());
					rgFiles[i]["filename"] = encoding.GetBytes(att.DisplayName);
					rgFiles[i]["contenttype"] = encoding.GetBytes(GetMIMEType(att.FileName));
					string file = FogBugzReport.GetTempFilePathWithExtension(Path.GetExtension(att.FileName));
					att.SaveAsFile(file);
					FileStream fs = new FileStream(file, FileMode.Open);
					BinaryReader br = new BinaryReader(fs);
					rgFiles[i]["data"] = br.ReadBytes((int)fs.Length);
					fs.Close();
					++i;
				}
				args.Add("nFileCount", mi.Attachments.Count.ToString());
			}
			ShowConfirmationDialog(api.Cmd("new", args, rgFiles));
		}

		private void ShowConfirmationDialog(string result) {
			if(ShowConfirmation) {
				using(ConfirmationForm form = new ConfirmationForm(url, result)) {
					form.ShowDialog();
				}
			}
		}

		protected override void CacheData(System.ComponentModel.BackgroundWorker bw) {
			data.Clear();
			//data.Add("project", api.XListProjects());
			data.Add("project", api.XCmd("listProjects", null, "response/projects"));
			bw.ReportProgress(30);
			data.Add("area", api.XCmd("listAreas", null, "response/areas"));
			bw.ReportProgress(40);
			data.Add("milestone", api.XCmd("listFixFors", null, "response/fixfors"));
			bw.ReportProgress(50);
			data.Add("category", api.XCmd("listCategories", null, "response/categories"));
			bw.ReportProgress(60);
			Dictionary<string, string> args = new Dictionary<string, string>();
			args.Add("fIncludeVirtual", "1");
			args.Add("fIncludeNormal", "1");
			data.Add("assignedTo", api.XCmd("listPeople", args, "response/people"));
			bw.ReportProgress(70);
			data.Add("priority", api.XCmd("listPriorities", null, "response/priorities"));
			bw.ReportProgress(80);
			Dictionary<string, string> sargs = new Dictionary<string,string>();
			sargs.Add("q", ""); // To search for everything, not just within current filter
			sargs.Add("max", "25"); // Return last 25 cases...
			sargs.Add("cols", "sTitle"); // Only return title column, ixBug is embedded as attribute of <case>
			XmlNodeList list = api.XCmd("search", sargs, "response/cases");
			data.Add("cases", list);
			bw.ReportProgress(100);
		}

		public override string[] GetProjects() {
			XmlNodeList list;
			if(data.TryGetValue("project", out list)) {
				list = list.Item(0).SelectNodes("project/sProject");
				string[] projects = new string[list.Count];
				int i=0;
				foreach(XmlNode node in list) {
					projects[i++] = node.InnerText;
				}
				return projects;
			}
			return null;
		}

		public override void ReportOnSite(string url, MailItem mi, string senderAddress) {
			base.ReportOnSite(url, mi, senderAddress);
			//url += "/default.asp?pg=pgEditBug&command=new";
			string title = "&sTitle=" + HttpUtility.UrlEncode(mi.Subject);
			string content = "&sEvent=" + HttpUtility.UrlEncode(mi.Body.Replace("HYPERLINK", "")); //mi.Body.Replace("\r\n", "%0D%0A").Replace("HYPERLINK", "").Replace(" ", "%20");
			string email = "&sCustomerEmail=" +  HttpUtility.UrlEncode(senderAddress);
			/*url += title + content + email;
			System.Diagnostics.Process.Start(url);*/
			url += "/default.asp";

			InternetExplorer IEControl = new InternetExplorer();
			IWebBrowserApp IE = (IWebBrowserApp)IEControl;
			IE.Visible = true;

			ASCIIEncoding Encode = new ASCIIEncoding();
			string postdata = "pg=pgEditBug&command=new" + title + content + email;

			//int i=0;
			byte[] post = Encode.GetBytes(postdata);
			ASCIIEncoding encoding = new ASCIIEncoding();
			using (MemoryStream ms = new MemoryStream()) {
				ms.Write(post, 0, post.Length);
			/*	foreach(Attachment att in mi.Attachments) {
					byte[] data = encoding.GetBytes("&name=File" + (i + 1).ToString());
					ms.Write(data, 0, data.Length);
					data = encoding.GetBytes("&filename=" + att.DisplayName);
					ms.Write(data, 0, data.Length);
					data = encoding.GetBytes("&contenttype=" + GetMIMEType(att.FileName) + "&data=");
					ms.Write(data, 0, data.Length);
					string file = FogBugzReport.GetTempFilePathWithExtension(Path.GetExtension(att.FileName));
					att.SaveAsFile(file);
					FileStream fs = new FileStream(file, FileMode.Open);
					BinaryReader br = new BinaryReader(fs);
					ms.Write(br.ReadBytes((int)fs.Length), 0, (int)fs.Length);
					++i;
				}
				if(mi.Attachments.Count > 0) {
					post = encoding.GetBytes("&nFileCount=" + mi.Attachments.Count.ToString());
					ms.Write(post, 0, post.Length);
				}*/
				post = ms.ToArray();

			}
			//args.Add("nFileCount", mi.Attachments.Count.ToString());
		//	string oooo = encoding.GetString(post);

			string header = "Content-Type: application/x-www-form-urlencoded";

			IE.Navigate(url, null, null, post, header);		 
		  
		}
	}
}
